package cn.linjianhui.api.client.invoker.impl;

import cn.linjianhui.api.client.DataFormat;
import cn.linjianhui.api.client.invoker.HttpClient;
import cn.linjianhui.api.client.invoker.HttpRequestParam;
import cn.linjianhui.api.client.invoker.Serializer;
import cn.linjianhui.api.client.util.HttpUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.StringEntity;
import org.springframework.util.Assert;

public class HttpClientImpl implements HttpClient {
    private static final String DEFAULT_USER_AGENT = "Rpc.API.Client";
    private static final String DEFAULT_CONTENT_TYPE = "application/json;charset=utf-8";

    private Serializer serializer;

    private DataFormat dataFormat;

    HttpClientImpl(Serializer serializer, DataFormat dataFormat) {
        this.serializer = serializer;
        this.dataFormat = dataFormat;
    }

    @Override
    public HttpResponse get(HttpClientTokenAuthenticator auth) throws Exception {
        Assert.notNull(auth, "HttpClientTokenAuthenticator cannot be null");
        HttpRequestBase request = getHttpRequest(auth, HttpMethod.GET);
        return HttpUtils.getHttpClient().execute(request);
    }

    @Override
    public HttpResponse post(HttpClientTokenAuthenticator auth) throws Exception {
        Assert.notNull(auth, "HttpClientTokenAuthenticator cannot be null");
        HttpRequestBase request = getHttpRequest(auth, HttpMethod.POST);
        return HttpUtils.getHttpClient().execute(request);
    }

    private HttpRequestBase getHttpRequest(HttpClientTokenAuthenticator auth, HttpMethod method) {
        HttpRequestParam requestParam = auth.getRequestParam();
        HttpRequestBase request;
        if(HttpMethod.GET == method) {
            request = new HttpGet(requestParam.getRequestUrl());
        }else {
            request = new HttpPost(requestParam.getRequestUrl());
        }

        request.addHeader("User-Agent", DEFAULT_USER_AGENT);

        switch (this.dataFormat) {
            case JSON:
                request.addHeader("Content-Type", "application/json;charset=utf-8");
                break;
            default:
                request.addHeader("Content-Type", DEFAULT_CONTENT_TYPE);
                break;
        }

        // 授权访问
        auth.authenticate();

        for (String key : requestParam.getHeaders().keySet()) {
            request.addHeader(key, requestParam.getHeaders().get(key));
        }

        if(HttpMethod.POST == method) {
            String json = this.serializer.serialize(requestParam.getBody());
            ((HttpPost) request).setEntity(new StringEntity(json, "UTF-8"));
        }

        return request;
    }

    private enum HttpMethod {
        GET, POST
    }
}
